package com.insight.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanqiao.insight.common.constant.CommonConstant;
import com.insight.common.util.IPUtils;
import com.insight.common.util.SpringContextUtils;
import com.insight.common.util.oConvertUtils;
import com.insight.modules.system.entity.SysDepartRolePermission;
import com.insight.modules.system.mapper.SysDepartRolePermissionMapper;
import com.insight.modules.system.service.ISysDepartRolePermissionService;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Description: 部门角色权限
 * @Author: jeecg-boot
 * @Date:   2020-02-12
 * @Version: V1.0
 */
@Service
public class SysDepartRolePermissionServiceImpl extends ServiceImpl<SysDepartRolePermissionMapper, SysDepartRolePermission> implements ISysDepartRolePermissionService {

    /**
     * 保存部门角色权限
     * 该方法会根据传入的当前权限IDs和历史权限IDs，自动计算新增和删除的权限，
     * 并批量执行数据库的添加和删除操作，保持部门角色权限数据同步。
     *
     * @param roleId            角色ID，用于关联权限
     * @param permissionIds     当前权限ID字符串，多个权限ID用逗号分隔，如："p1,p2,p3"
     * @param lastPermissionIds 历史权限ID字符串，多个权限ID用逗号分隔
     */
    @Override
    public void saveDeptRolePermission(String roleId, String permissionIds, String lastPermissionIds) {
        String ip = CommonConstant.LOCAL_IP;
            // 尝试从当前HTTP请求中获取客户端IP地址，用于记录操作来源
        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
        ip = IPUtils.getIpAddr(request);

        // 计算需要新增的权限ID集合（即当前权限中有，但历史权限中没有的权限）
        List<String> add = getDiff(lastPermissionIds, permissionIds);
        if (add != null && add.size() > 0) {
            List<SysDepartRolePermission> list = new ArrayList<>();
            // 遍历新增权限ID集合，构造实体对象并设置元数据
            for (String p : add) {
                if (oConvertUtils.isNotEmpty(p)) {
                    SysDepartRolePermission rolepms = new SysDepartRolePermission(roleId, p);
                    rolepms.setOperateDate(new Date()); // 记录操作时间
                    rolepms.setOperateIp(ip);           // 记录操作IP
                    list.add(rolepms);
                }
            }
            // 批量保存新增的部门角色权限
            this.saveBatch(list);
        }

        // 计算需要删除的权限ID集合（即历史权限中有，但当前权限中没有的权限）
        List<String> delete = getDiff(permissionIds, lastPermissionIds);
        if (delete != null && delete.size() > 0) {
            // 遍历删除权限ID集合，逐个删除对应的部门角色权限记录
            for (String permissionId : delete) {
                this.remove(new QueryWrapper<SysDepartRolePermission>().lambda()
                        .eq(SysDepartRolePermission::getRoleId, roleId)
                        .eq(SysDepartRolePermission::getPermissionId, permissionId));
            }
        }
    }

    /**
     * 计算差异集合：找出diff字符串中存在但main字符串中不存在的元素
     *
     * 作用是辅助权限增删操作时找出新增或需删除的权限ID列表。
     *
     * @param main  基准字符串，多个元素用逗号分隔（如历史权限ID）
     * @param diff 对比字符串，多个元素用逗号分隔（如当前权限ID）
     * @return 返回diff中独有的元素列表，若diff为空则返回null，main为空则返回diff所有元素
     */
    private List<String> getDiff(String main, String diff) {
        // 若diff为空，则没有差异，直接返回null
        if (oConvertUtils.isEmpty(diff)) {
            return null;
        }
        // 若main为空，则差异就是diff所有元素，直接拆分返回
        if (oConvertUtils.isEmpty(main)) {
            return Arrays.asList(diff.split(","));
        }

        // 将main拆分成数组并放入HashMap作为快速查找结构
        String[] mainArr = main.split(",");
        String[] diffArr = diff.split(",");
        Map<String, Integer> map = new HashMap<>();
        for (String string : mainArr) {
            map.put(string, 1); // value无实际意义，只用于判断是否包含key
        }

        List<String> res = new ArrayList<>();
        // 遍历diff数组，判断元素是否不在main中
        for (String key : diffArr) {
            // 过滤空字符串，且只添加main中不存在的元素
            if (oConvertUtils.isNotEmpty(key) && !map.containsKey(key)) {
                res.add(key);
            }
        }
        return res;
    }
}

